/**
 * Licensed under the Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0
 * @brief FreeRTOS应用示例
 * @details
 * @author 王炸物联网https://blog.csdn.net/wangyx1234?spm=1000.2115.3001.5343
 * @date 2022
 * @version 1.0
 * @copyright 版权所有，禁止用于商业用途
 */
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"

TaskHandle_t task1; // 任务1结构对象
TaskHandle_t task2;
TaskHandle_t task3;

static int task1_flag;           // 用于指示任务运行状态的标志变量
static int task2_flag;           
static int task3_flag;           

bool wait_event(const char* TAG)
{
    uint32_t notify_value;
    xTaskNotifyWait(0, 0xFFFFFFFF, &notify_value, portMAX_DELAY);
    printf("%s: notify num: %u\r\n",TAG, notify_value);
    return true;
}

void process_event(void)
{
    task1_flag++;
}

void notify_other_tasks(void)
{
    xTaskNotifyGive(task3);
}

/**
 * 任务的运行代码
 * @param param 任务初始运行参数
 */
static void task1_process(void *arg)
{
    static const char *TASK1_TAG = "TASK1";
    while (1) {
        if(wait_event(TASK1_TAG)) {
            process_event();
            notify_other_tasks();
        }
    }
}

static void task2_process(void *arg)
{
    static const char *TASK2_TAG = "TASK2";
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(2000));
        printf("%s: task2_flag = %d\r\n", TASK2_TAG, task2_flag);
        task2_flag++;
        xTaskNotify(task1, task2_flag, eSetValueWithOverwrite);
    }
}

static void task3_process(void *arg)
{
    static const char *TASK3_TAG = "TASK3";
    while (1) {
        uint32_t ret = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        printf("%s: task3_flag = %d, ret = %u\r\n", TASK3_TAG, task3_flag, ret);
        task3_flag++;
    }
}

static void init(void) {
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
            CONFIG_IDF_TARGET,
            chip_info.cores,
            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}

void app_main(void)
{
    init();
    /*
    static BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *constpcName, const uint32_t usStackDepth, 
    void *constpvParameters, UBaseType_t uxPriority, TaskHandle_t *constpxCreatedTask)*/
    xTaskCreate(&task1_process, "task1", 1024*2, (void *)"1", configMAX_PRIORITIES, &task1); // configMAX_PRIORITIES = 25
    xTaskCreate(&task2_process, "task2", 1024*2, (void *)"2", configMAX_PRIORITIES-2, &task2);
    xTaskCreate(&task3_process, "task3", 1024*2, (void *)"3", configMAX_PRIORITIES-2, &task3);
}
